﻿#include "GlobalHelper.h"

#ifdef Q_OS_WIN
#include <windows.h>
#include <tlhelp32.h>
#define WIN32_LEAN_AND_MEAN             // 从 Windows 头文件中排除极少使用的内容
#include <locale>
#endif // Q_OS_WIN

#include <QProcess>
#include <QCoreApplication>
#include <QUuid>
#include <QFile>
#include <QTextStream>
#include <QRegExp>
#include <QRegularExpression>
#include <tuple>
#include <array>
#include <QDomElement>
#include <QDomDocument>
#include <QDomAttr>
#include <QDir>
#include <QTime>
#include <QDebug>
#include <QFileInfo>
#include <QtGlobal>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>

#include "IBaseSignal.h"

using namespace std;

namespace BaseModule
{
    QString GlobalHelper::m_tempIODir = "";
    QString GlobalHelper::m_projectName = "";

    void GlobalHelper::setIsOpenProject(bool isOpenProject)
    {
        m_isOpenProject = isOpenProject;
    }
    bool GlobalHelper::getIsOpenProject()
    {
        return m_isOpenProject;
    }

    qint64 GlobalHelper::getTimestamp()
    {
        return QDateTime::currentDateTime().toMSecsSinceEpoch();
    }

    QString GlobalHelper::getTimestampString()
    {
        return QString::number(QDateTime::currentDateTime().toMSecsSinceEpoch());
    }

    void GlobalHelper::sendMsgToParentProcess(QString msg)
    {
        fputs(msg.toLocal8Bit(), stdout);
        fflush(stdout);
    }

    std::wstring GlobalHelper::stringToWString(const std::string data)
    {
        if (!data.size()) return {};

        size_t _len = data.size() + 1;
        wchar_t* _dataW = (wchar_t*)malloc(2 * _len);
        memset(_dataW, 0, 2 * _len);
        size_t _converted = 0;

        std::locale _old_loc = std::locale::global(std::locale(""));
        mbstowcs_s(&_converted, _dataW, _len, data.data(), _TRUNCATE);
        std::locale::global(_old_loc);

        std::wstring _filePath_U = _dataW;
        free(_dataW);
        _dataW = nullptr;

        return _filePath_U;
    }

    qint64 GlobalHelper::getProcessIdByName(std::string processName)
    {
        DWORD processId = 0;
        HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        if (snapshot != INVALID_HANDLE_VALUE)
        {
            PROCESSENTRY32 processEntry;
            processEntry.dwSize = sizeof(PROCESSENTRY32);
            if (Process32First(snapshot, &processEntry))
            {
                do
                {
                    if (strcmp(processEntry.szExeFile, processName.data()) == 0)
                    {
                        processId = processEntry.th32ProcessID;
                        break;
                    }
                } while (Process32Next(snapshot, &processEntry));
            }
            CloseHandle(snapshot);
        }
        return processId;
    }


    /// @brief 通过进程id关闭进程

    void GlobalHelper::closeProcessByProcessId(qint64 processId)
    {
        HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, processId);
        if (hProcess != NULL)
        {
            TerminateProcess(hProcess, 0);
            CloseHandle(hProcess);
        }
    }


    /// @brief 将 QString ,QString QList拼接为QString
    QString GlobalHelper::convertQStringQStringQListToQString(const QList<QPair<QString, QString>>& data)
    {
        QString _str;
        for (auto i = data.cbegin(); i != data.cend(); i++)
        {
            _str = _str + i->first + ";;" + i->second.trimmed() + "//";//去掉换行符
        }
        return _str;
    }

    /// @brief 将char*解析为 QString,QString QList
    QList<QPair<QString, QString>> GlobalHelper::convertStringToQStringQStringQList(QString data)
    {
        QList<QPair<QString, QString>> List;
        auto _stringList = data.split("//");
        _stringList.removeAll("");
        bool _success;
        QString _key;
        QString _value;
        for (QString item : _stringList)
        {
            auto _keyValueStr = item.split(";;");
            _keyValueStr.removeAll("");
            if (_keyValueStr.count() == 2)
            {
                _key = _keyValueStr[0];
                _value = _keyValueStr[1];
                List.append(QPair<QString, QString>(_key, _value));
            }
        }
        return List;
    }

    /// @brief 将 QPair int int QList拼接为QString , python接口相关
    QString GlobalHelper::convertPairIntIntListToQString(QList<QPair<int, QList<int>>> data)
    {
        QString _str;
        for (auto i = data.cbegin(); i != data.cend(); i++)
        {
            QString _secondStr;
            for (auto j = i->second.cbegin(); j != i->second.cend(); j++)
            {
                _secondStr = _secondStr + QString::number(*j) + ";";
            }
            _str = _str + QString::number(i->first) + "," + _secondStr + "|";
        }
        return _str;
    }

    /// @brief 将char*解析为 QPair int int QList , python接口相关
    QList<QPair<int, QList<int>>> GlobalHelper::convertStringToPairIntIntList(char* data)
    {
        QList<QPair<int, QList<int>>> _list;

        QString dataStr(data);
        auto _stringList = dataStr.split('|');
        _stringList.removeAll("");
        bool _success1 = false;
        bool _success2 = false;
        int _key;
        for (QString item : _stringList)
        {
            QList<int> _subList;
            auto _keyValueStr = item.split(',');
            _keyValueStr.removeAll("");
            if (_keyValueStr.count() == 2)
            {
                _key = _keyValueStr[0].toInt(&_success1);
                auto _subListStr = _keyValueStr[1].split(';');
                _subListStr.removeAll("");
                for (auto j : _subListStr)
                {
                    auto _value = j.toInt(&_success2);
                    if (_success2)
                    {
                        _subList.append(_value);
                    }
                }

                if (_success1)
                {
                    _list.append(QPair<int, QList<int>>(_key, _subList));
                }
                else
                {
                    _list.clear();
                    QString msg = QObject::tr("convert char* to QMultiHash<int,int> fail! content:%1").arg(dataStr);
                    return _list;
                }
            }
        }
        return _list;
    }

    /// @brief 将char*解析为 int QList , python接口相关

    bool GlobalHelper::readFile(QString filePath, QByteArray& content)
    {
        try
        {
            QFile file(filePath);
            if (!file.exists())
            {
                //emit IBaseSignalInstance->signal_showMessageToConsole(BaseModule::EMessageConsole::Error_Message, QObject::tr("Read file fail! file not exist! file path:%1").arg(filePath));
                return false;
            }
            if (!file.open(QIODevice::ReadOnly))
            {
                //emit IBaseSignalInstance->signal_showMessageToConsole(BaseModule::EMessageConsole::Error_Message, QObject::tr("Read file fail! open failed! file path:%1").arg(filePath));
                return false;
            }

            QTextStream jsonStream(&file);
            jsonStream.setCodec("UTF-8");
            content = jsonStream.readAll().toUtf8();
            file.close();
            return true;
        }
        catch (const std::exception&)
        {
            //emit IBaseSignalInstance->signal_recordSimulationProcess(int(BaseModule::EMessageConsole::Normal_Message), "catch readFile exception!");
            return false;
        }
    }

    bool GlobalHelper::writeFile(QString filePath, QByteArray content, QIODevice::OpenMode openModel)
    {
        QFile file(filePath);
        if (!file.open(openModel))
        {
            //emit IBaseSignalInstance->signal_showMessageToConsole(BaseModule::EMessageConsole::Error_Message, QObject::tr("Write file fail! open failed! file path:%1").arg(filePath));
            return false;
        }
        QTextStream stream(&file);
        stream.setCodec("UTF-8");
        stream << content << "\n";
        file.close();
        return true;
    }

    void GlobalHelper::initProjectTempDir(bool isFromReport)
    {
        m_installDir = qApp->applicationDirPath().mid(0, qApp->applicationDirPath().lastIndexOf('/'));
        m_tempIODir = m_installDir + "/tempIO";
        if (isFromReport)
        {
            QDir _dir(m_tempIODir);
            if (_dir.exists(m_tempIODir))
            {
                return;
            }
        }
        createTempDir();
        createSimulationDataTempDir();
        createImportDataTempDir();

        m_recordScriptFilePath = QString("%1/RecordScript.py").arg(m_tempIODir);
    }

    bool GlobalHelper::createTempDir()
    {
        QDir _dir(m_tempIODir);
        bool result = false;

        //创建tempIO
        if (_dir.exists(m_tempIODir))
        {
            _dir.removeRecursively();
        }
        result = _dir.mkdir(m_tempIODir);
        return (result);
    }

    bool GlobalHelper::CurrentInstallationDirectoryPathConversion(QString& path)
    {
        QList<QString> filePaths = m_simulationDataFilePath.split(',');
        for (const auto& _filePath : filePaths)
        {
            QString marker = "/" + _filePath.split('/').last();
            int markerIndex = path.indexOf(marker);
            if (markerIndex != -1)
            {
                path = GlobalHelperInstance->getSimulationDataTempDir() + path.mid(markerIndex);
                return true;
            }
        }
        return false;
    }

    QString GlobalHelper::getProjectTempIODir()
    {
        return m_tempIODir;
    }

    QString GlobalHelper::getProjectTempFilePath()
    {
        if (m_projectName.isEmpty())
            return "";
        return m_tempIODir + "/" + m_projectName;
    }

    /// @brief 获取记录脚本的文件路径

    QString GlobalHelper::getFileNameByFilePath(QString filePath)
    {
        return filePath.split('/').last().remove(".ppc");
    }

    bool GlobalHelper::canCreateProjectTempDir(QString projectFilePath)
    {
        QString projectName = getFileNameByFilePath(projectFilePath);
        if (projectName.isEmpty())
            return false;
        QString projectTempIO = QString("%1/%2").arg(m_tempIODir).arg(projectName);
        QDir dir;
        if (dir.exists(projectTempIO))
        {
            dir.remove(projectTempIO);
        }
        return true;
    }

    bool GlobalHelper::createProjectTempDir(QString projectFilePath)
    {
        if (!canCreateProjectTempDir(projectFilePath))
        {
            return false;
        }
        m_projectName = getFileNameByFilePath(projectFilePath);
        QDir _dir;
        bool _result = false;
        QString _filePath = m_tempIODir + "/" + getFileNameByFilePath(projectFilePath);
        _result = _dir.mkdir(_filePath);

        if (!_result)
        {
            return false;
        }
        return true;
    }

    bool GlobalHelper::deleteProjectTempDir()
    {
        QString _filePath = m_tempIODir + "/" + m_projectName;
        QDir _dir(_filePath);
        bool result = false;
        if (_dir.exists(_filePath))
        {
            result = _dir.removeRecursively();
        }
        return result;
    }

    QString GlobalHelper::getRecordScriptFilePath()
    {
        return m_recordScriptFilePath;
    }

    QString GlobalHelper::getAppInstallDir()
    {
        return m_installDir;
    }

    //用户目录有中文时，该方式有问题
    QPair<std::string, std::string> GlobalHelper::getUserTempPath()
    {
        char tempPath[MAX_PATH];
        DWORD length = GetTempPathA(MAX_PATH, tempPath);
        if (!(length > 0))
        {
            qDebug() << "Failed to get temporary folder path";
        }

        std::string _forwardSlashPath = tempPath;
        std::string _backwardSlashPath = tempPath;
        for (size_t i = 0; i < _forwardSlashPath.length(); ++i)
        {
            if (_forwardSlashPath[i] == '\\')
            {
                _forwardSlashPath[i] = '/';
            }
        }
        return QPair{ _forwardSlashPath, _backwardSlashPath };
    }

    /// @brief 判断名字是否合法，只能由字母数字下划线组成、不是空的、长度不大于100
    bool GlobalHelper::isLegalName(QString& name)
    {
        name = name.trimmed();
        bool result = true;
        QString errorMsg;
        if (name.isEmpty())
        {
            //errorMsg = QObject::tr("name is illegal,name can not be empty");
            errorMsg = QStringLiteral("报告名称不能为空");

            result = false;
        }
        else if (name.length() > 32)
        {
            //errorMsg = QObject::tr("name is illegal,the length of the name cannot exceed 100");
            errorMsg = QStringLiteral("报告名称长度不能超过32");
            result = false;
        }
        else
        {
            // 仅支持中文、下划线、加号、连字符、数字、英文六种字符
            QRegularExpression regex1("^[\u4e00-\u9fa5a-zA-Z0-9_+-]+$");
            // _+-三个符号可同时存在但不能连续使用
            QRegularExpression regex2("[_+-]{2,}");
            // 不允许文件名以 _+- 三个符号开头，文件以中文、字母、数字开头
            QRegularExpression regex3("^[^_+-].*");
            if (!regex1.match(name).hasMatch())
            {
                errorMsg = QStringLiteral("报告名称仅支持中文、下划线（_）、连字符（-）、加号（+）、数字、英文六种字符");
                result = false;
            }
            else if (!regex3.match(name).hasMatch())
            {
                result = false;
                errorMsg = QStringLiteral("文件名不允许以符号开头");
            }
            else if (regex2.match(name).hasMatch())
            {
                result = false;
                errorMsg = QStringLiteral("任意符号不可连续使用");
            }
        }

        if (result)
        {
            return true;
        }
        else
        {
            emit IBaseSignalInstance->signal_sendErrorMessageToUI(errorMsg);
            return false;
        }
    }


    /// @brief 获取线宽数组

    QStringList GlobalHelper::getLineWidthList()
    {
        return { "0.5", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" };
    }

    /// @brief 获取字体大小数组

    QStringList GlobalHelper::getFontSizeList()
    {
        return { "8", "9", "10", "11", "12", "14", "16", "18", "20", "22", "24", "26", "28", "36", "42", "72" };
    }

    /// @brief 将 int, int QMultiHash拼接为QString , python接口相关

    QString GlobalHelper::convertIntIntHashToQString(QMultiHash<int, int> data)
    {
        QString _str;
        for (auto i = data.cbegin(); i != data.cend(); i++)
        {
            _str = _str + QString::number(i.key()) + "," + QString::number(i.value()) + "|";
        }
        return _str;
    }

    /// @brief 将char*解析为 int, int QMultiHash , python接口相关

    QMultiHash<int, int> GlobalHelper::convertStringToIntIntHash(char* data)
    {
        QMultiHash<int, int> _hash;
        QString dataStr(data);
        auto _stringList = dataStr.split('|');
        _stringList.removeAll("");
        bool _success1;
        bool _success2;
        int _key, _value;
        for (QString item : _stringList)
        {
            auto _keyValueStr = item.split(',');
            _keyValueStr.removeAll("");
            if (_keyValueStr.count() == 2)
            {
                _key = _keyValueStr[0].toInt(&_success1);
                _value = _keyValueStr[1].toInt(&_success2);

                if (_success1 && _success2)
                {
                    _hash.insert(_key, _value);
                }
                else
                {
                    _hash.clear();
                    QString msg = QObject::tr("convert char* to QMultiHash<int,int> fail! content:%1").arg(dataStr);
                    //emit IBaseSignalInstance->signal_showMessageType((int)BaseModule::MessageType::Error_Message, msg);
                    return _hash;
                }
            }
        }
        return _hash;
    }

    /// @brief 将char*解析为 int, int QMultiHash , python接口相关

    QMultiHash<int, int> GlobalHelper::convertStringToIntIntHash(QString data)
    {
        QMultiHash<int, int> _hash;
        auto _stringList = data.split('|');
        _stringList.removeAll("");
        bool _success1;
        bool _success2;
        int _key, _value;
        for (QString item : _stringList)
        {
            auto _keyValueStr = item.split(',');
            _keyValueStr.removeAll("");
            if (_keyValueStr.count() == 2)
            {
                _key = _keyValueStr[0].toInt(&_success1);
                _value = _keyValueStr[1].toInt(&_success2);

                if (_success1 && _success2)
                {
                    _hash.insert(_key, _value);
                }
                else
                {
                    _hash.clear();
                    QString msg = QObject::tr("convert char* to QMultiHash<int,int> fail! content:%1").arg(data);
                    //emit IBaseSignalInstance->signal_showMessageType((int)BaseModule::MessageType::Error_Message, msg);
                    return _hash;
                }
            }
        }
        return _hash;
    }

    QString GlobalHelper::convertIntIntQListToQString(const QList<QPair<int, int>>& data)
    {
        QString _str;
        for (auto i = data.cbegin(); i != data.cend(); i++)
        {
            _str = _str + QString::number(i->first) + "," + QString::number(i->second) + "|";
        }
        return _str;
    }

    QList<QPair<int, int>> GlobalHelper::convertStringToIntIntQList(char* data)
    {
        QList<QPair<int, int>> intList;
        QString dataStr(data);
        auto _stringList = dataStr.split('|');
        _stringList.removeAll("");
        bool _success1;
        bool _success2;
        int _key, _value;
        for (QString item : _stringList)
        {
            auto _keyValueStr = item.split(',');
            _keyValueStr.removeAll("");
            if (_keyValueStr.count() == 2)
            {
                _key = _keyValueStr[0].toInt(&_success1);
                _value = _keyValueStr[1].toInt(&_success2);

                if (_success1 && _success2)
                {
                    intList.append(QPair<int, int>(_key, _value));
                }
                else
                {
                    intList.clear();
                    QString msg = QObject::tr("convert char* to QMultiHash<int,int> fail! content:%1").arg(dataStr);
                    //emit IBaseSignalInstance->signal_showMessageType((int)BaseModule::MessageType::Error_Message, msg);
                    return intList;
                }
            }
        }
        return intList;
    }

    QList<QPair<int, int>> GlobalHelper::convertStringToIntIntQList(QString data)
    {
        QList<QPair<int, int>> intList;
        auto _stringList = data.split('|');
        _stringList.removeAll("");
        bool _success1;
        bool _success2;
        int _key, _value;
        for (QString item : _stringList)
        {
            auto _keyValueStr = item.split(',');
            _keyValueStr.removeAll("");
            if (_keyValueStr.count() == 2)
            {
                _key = _keyValueStr[0].toInt(&_success1);
                _value = _keyValueStr[1].toInt(&_success2);

                if (_success1 && _success2)
                {
                    intList.append(QPair<int, int>(_key, _value));
                }
                else
                {
                    intList.clear();
                    QString msg = QObject::tr("convert char* to QMultiHash<int,int> fail! content:%1").arg(data);
                    //emit IBaseSignalInstance->signal_showMessageType((int)BaseModule::MessageType::Error_Message, msg);
                    return intList;
                }
            }
        }
        return intList;
    }

    /// @brief 将 QString, double QList拼接为QString , python接口相关
    QString GlobalHelper::convertQStringDoubleQPairToQString(const QPair<QString, double>& data)
    {
        QString _str;
        _str = _str + data.first + "," + QString::number(data.second) + "|";
        return _str;
    }

    /// @brief 将char*解析为 QString, double QList , python接口相关
    QPair<QString, double> GlobalHelper::convertStringToQStringDoublePair(QString data)
    {
        QPair<QString, double> Pair;
        auto _stringList = data.split('|');
        _stringList.removeAll("");
        bool _success;
        QString _key;
        double _value;

        for (QString item : _stringList)
        {
            auto _keyValueStr = item.split(',');
            _keyValueStr.removeAll("");
            if (_keyValueStr.count() == 2)
            {
                _key = _keyValueStr[0];
                _value = _keyValueStr[1].toDouble(&_success);

                if (_success)
                {
                    Pair.first = _key;
                    Pair.second = _value;
                }
                else
                {
                    QString msg = QObject::tr("convert char* to QPair<QString, double> fail! content:%1").arg(data);
                    //emit IBaseSignalInstance->signal_showMessageType((int)BaseModule::MessageType::Error_Message, msg);
                    return Pair;
                }
            }
        }
        return Pair;
    }

    /// @brief 将 int ,QString QList拼接为QString , python接口相关
    QString GlobalHelper::convertIntQStringQListToQString(const QList<QPair<int, QString>>& data)
    {
        QString _str;
        for (auto i = data.cbegin(); i != data.cend(); i++)
        {
            _str = _str + QString::number(i->first) + ";" + i->second + "|";
        }
        return _str;
    }

    /// @brief 将QList<QList<int>> 拼接为QString
    QString GlobalHelper::convertQListQListIntToQString(const QList<QList<int>>& data)
    {
        QString _str;
        for (auto i : data)
        {
            for (auto j : i)
            {
                _str = _str + QString::number(j) + ",";
            }
            _str += "|";
        }
        return _str;
    }

    /// @brief 将QString转为QList<QList<int>> 
    QList<QList<int>> GlobalHelper::convertQStringToQListQListInt(const QString& data)
    {
        QList<QList<int>> _result;
        QStringList _array = data.split('|');
        for (auto i : _array)
        {
            if (!i.isEmpty())
            {
                auto _j = i.split(',');
                QList<int> _temp;
                for (auto a : _j)
                {
                    if (!a.isEmpty())
                    {
                        _temp.append(a.toInt());
                    }
                }
                _result.append(_temp);
            }
        }
        return _result;
    }

    /// @brief 将char*解析为 int,QString QList , python接口相关
    QList<QPair<int, QString>> GlobalHelper::convertStringToIntQStringQList(QString data)
    {
        QList<QPair<int, QString>> List;
        auto _stringList = data.split('|');
        _stringList.removeAll("");
        bool _success;
        int _key;
        QString _value;
        for (QString item : _stringList)
        {
            auto _keyValueStr = item.split(';');
            _keyValueStr.removeAll("");
            if (_keyValueStr.count() == 2)
            {
                _key = _keyValueStr[0].toInt(&_success);
                _value = _keyValueStr[1];

                if (_success)
                {
                    List.append(QPair<int, QString>(_key, _value));
                }
                else
                {
                    List.clear();
                    QString msg = QObject::tr("convert char* to QMultiHash<int,QString> fail! content:%1").arg(data);
                    //emit IBaseSignalInstance->signal_showMessageType((int)BaseModule::MessageType::Error_Message, msg);
                    return List;
                }
            }
        }
        return List;
    }

    /// @brief 将 double QList拼接为QString , python接口相关

    QString GlobalHelper::convertDoubleListToQString(QList<double> data)
    {
        QString _str;
        for (auto item : data)
        {
            _str += QLocale().toString(item, 'g', QLocale::FloatingPointShortest).remove(",") + ",";
        }
        return _str;
    }

    /// @brief 将char*解析为 double QList , python接口相关

    QList<double> GlobalHelper::convertStringToDoubleList(char* data)
    {
        QList<double> _list;
        QString dataStr(data);
        auto _stringList = dataStr.split(',');
        _stringList.removeAll("");
        bool result;
        double value;
        for (QString item : _stringList)
        {
            value = item.toDouble(&result);
            if (result)
            {
                _list.append(value);
            }
            else
            {
                _list.clear();
                QString msg = QObject::tr("convert char* to QList<double> fail! content:%1").arg(dataStr);
                //emit IBaseSignalInstance->signal_showMessageType((int)BaseModule::MessageType::Error_Message, msg);
                return _list;
            }
        }
        return _list;
    }

    /// @brief 将char*解析为 double QList , python接口相关

    QList<double> GlobalHelper::convertStringToDoubleList(QString data)
    {
        QList<double> _list;
        auto _stringList = data.split(',');
        _stringList.removeAll("");
        bool result;
        double value;
        for (QString item : _stringList)
        {
            value = item.toDouble(&result);
            if (result)
            {
                _list.append(value);
            }
            else
            {
                _list.clear();
                QString msg = QObject::tr("convert char* to QList<double> fail! content:%1").arg(data);
                //emit IBaseSignalInstance->signal_showMessageType((int)BaseModule::MessageType::Error_Message, msg);
                return _list;
            }
        }
        return _list;
    }

    /// @brief 将 int QList 拼接为QString , python接口相关

    QString GlobalHelper::convertIntListToQString(QList<int> data)
    {
        QString _str;
        for (auto item : data)
        {
            _str = _str + QString::number(item) + ",";
        }
        return _str;
    }

    /// @brief 将char*解析为 int QList , python接口相关

    QList<int> GlobalHelper::convertStringToIntList(char* data)
    {
        QList<int> list;
        QString dataStr(data);
        auto stringList = dataStr.split(',');
        stringList.removeAll("");
        bool result;
        int value;
        for (QString item : stringList)
        {
            value = item.toInt(&result);
            if (result)
            {
                list.append(value);
            }
            else
            {
                QString msg = QObject::tr("convert char* to QList<int> fail! content:%1").arg(dataStr);
                //emit IBaseSignalInstance->signal_showMessageType((int)BaseModule::MessageType::Error_Message, msg);
                list.clear();
                return list;
            }
        }
        return list;
    }
    /// @brief 将char*解析为 int QList , python接口相关


    QList<int> GlobalHelper::convertStringToIntList(QString data)
    {
        QList<int> list;
        auto stringList = data.split(',');
        stringList.removeAll("");
        bool result;
        int value;
        for (QString item : stringList)
        {
            value = item.toInt(&result);
            if (result)
            {
                list.append(value);
            }
            else
            {
                QString msg = QObject::tr("convert char* to QList<int> fail! content:%1").arg(data);
                //emit IBaseSignalInstance->signal_showMessageType((int)BaseModule::MessageType::Error_Message, msg);
                list.clear();
                return list;
            }
        }
        return list;
    }

    QString GlobalHelper::converQListQStringToQStrng(const QList<QString>& data, const QString& separator)
    {
        QString str{};
        for (const auto& i : data)
        {
            str.append(i + separator);
        }
        return str;
    }

    QList<QString> GlobalHelper::converQStrngToQListQString(const QString& data, const QString& separator)
    {
        QList<QString> strList{};
        auto _stringList = data.split(separator);
        _stringList.removeAll("");
        for (const auto& i : _stringList)
        {
            strList.append(i);
        }
        return strList;
    }

    QString GlobalHelper::convertQHashQStringIntToQString(const QHash<QString, int>& data)
    {
        QString _res;
        for (auto i = data.cbegin(); i != data.cend(); i++)
        {
            _res = _res + i.key() + "," + QString::number(i.value()) + "|";
        }
        return _res;
    }

    QHash<QString, int> GlobalHelper::convertQStringToQHashQStringInt(const QString& data)
    {
        QHash<QString, int> _hash;
        auto _stringList = data.split('|');
        _stringList.removeAll("");
        bool _success2;
        QString _key;
        int _value;
        for (QString item : _stringList)
        {
            auto _keyValueStr = item.split(',');
            _keyValueStr.removeAll("");
            if (_keyValueStr.count() == 2)
            {
                _key = _keyValueStr[0];
                _value = _keyValueStr[1].toInt(&_success2);

                if (_success2)
                {
                    _hash.insert(_key, _value);
                }
                else
                {
                    _hash.clear();
                    QString msg = QObject::tr("convert char* to QMultiHash<QString,int> fail! content:%1").arg(data);
                    return _hash;
                }
            }
        }
        return _hash;

    }

    QString GlobalHelper::convertQListTupleToIntIntQStringToQString(const QList<std::tuple<int, int, QString>>& data)
    {
        QString _str;
        for (auto i = data.cbegin(); i != data.cend(); i++)
        {
            _str = _str + QString::number(std::get<0>(*i)) + "," + QString::number(std::get<1>(*i)) + "," + std::get<2>(*i) + "|";
        }
        return _str;
    }

    QList<std::tuple<int, int, QString>> GlobalHelper::convertQStringToQListTupleToIntIntQString(const QString& data)
    {
        QList<std::tuple<int, int, QString>> _list;
        auto _stringList = data.split('|');
        _stringList.removeAll("");
        bool _success1;
        bool _success2;
        int _key, _value;
        QString _valueStr;
        for (QString item : _stringList)
        {
            auto _keyValueStr = item.split(',');
            _keyValueStr.removeAll("");
            if (_keyValueStr.count() == 3)
            {
                _key = _keyValueStr[0].toInt(&_success1);
                _value = _keyValueStr[1].toInt(&_success2);
                _valueStr = _keyValueStr[2];

                if (_success1 && _success2)
                {
                    _list.append(std::make_tuple(_key, _value, _valueStr));
                }
                else
                {
                    _list.clear();
                    QString msg = QObject::tr("convert char* to QList<std::tuple<int, int, QString>> fail! content:%1").arg(data);
                    // emit IBaseSignalInstance->signal_showMessageType((int)BaseModule::MessageType::Error_Message, msg);
                    return _list;
                }
            }
        }
        return _list;
    }

           // std::tuple<int, int, QString>转Qstring
    QString GlobalHelper::convertTupleToIntIntQStringToQString(const std::tuple<int, int, QString>& data)
    {
        QString _str;
        _str = _str + QString::number(std::get<0>(data)) + "," + QString::number(std::get<1>(data)) + "," + std::get<2>(data);
        return _str;
    }

    // QString转std::tuple<int, int, QString>
    std::tuple<int, int, QString> GlobalHelper::convertQStringToTupleToIntIntQString(const QString& data)
    {
        std::tuple<int, int, QString> _tuple;
        auto _stringList = data.split(',');
        _stringList.removeAll("");
        bool _success1;
        bool _success2;
        int _key, _value;
        QString _valueStr;
        if (_stringList.count() == 3)
        {
            _key = _stringList[0].toInt(&_success1);
            _value = _stringList[1].toInt(&_success2);
            _valueStr = _stringList[2];

            if (_success1 && _success2)
            {
                _tuple = std::make_tuple(_key, _value, _valueStr);
            }
            else
            {
                QString msg = QObject::tr("convert char* to std::tuple<int, int, QString> fail! content:%1").arg(data);
                return _tuple;
            }
        }
        else
        {
            QString msg = QObject::tr("convert char* to std::tuple<int, int, QString> fail! content:%1").arg(data);
            return _tuple;
        }
        return _tuple;
    }

    QString GlobalHelper::convertQPairQStringQVectorDoubleToQString(const QPair<QString, QVector<double>>& data)
    {
        QString _str;
        _str = _str + data.first + "|";
        for (auto item : data.second)
        {
            _str = _str + QLocale().toString(item, 'g', QLocale::FloatingPointShortest).remove(",") + ",";
        }
        return _str;
    }

    QPair<QString, QVector<double>> GlobalHelper::convertQStringToQPairQStringQVectorDouble(const QString& data)
    {
        QPair<QString, QVector<double>> _pair;
        auto _stringList = data.split('|');
        _stringList.removeAll("");
        bool _success = false;
        QString _key;
        QVector<double> _value;
        if (_stringList.count() == 2)
        {
            _key = _stringList[0];
            auto _valueStrList = _stringList[1].split(',');
            _valueStrList.removeAll("");
            for (auto item : _valueStrList)
            {
                _value.append(item.toDouble(&_success));
            }
            if (_success)
            {
                _pair.first = _key;
                _pair.second = _value;
            }
            else
            {
                _pair.first = "";
                _pair.second.clear();
                QString msg = QObject::tr("convert char* to QPair<QString, QVector<double>> fail! content:%1").arg(data);
                return _pair;
            }
        }
        else
        {
            _pair.first = "";
            _pair.second.clear();
            QString msg = QObject::tr("convert char* to QPair<QString, QVector<double>> fail! content:%1").arg(data);
            return _pair;
        }
        return _pair;
    }

    QString GlobalHelper::convertQVectorDoubleToQString(const QVector<double>& data)
    {
        QString _str;
        for (auto item : data)
        {
            _str = _str + QLocale().toString(item, 'g', QLocale::FloatingPointShortest).remove(",") + ",";
        }
        return _str;
    }

    QVector<double> GlobalHelper::convertQStringToQVectorDouble(const QString& data)
    {
        QVector<double> _vector;
        auto _stringList = data.split(',');
        _stringList.removeAll("");
        bool _success = false;
        for (auto item : _stringList)
        {
            _vector.append(item.toDouble(&_success));
        }
        return _vector;
    }

    QString GlobalHelper::convertQListDoubleToQString(const QList<double>& data)
    {
        QString _str;
        for (auto item : data)
        {
            _str = _str + QLocale().toString(item, 'g', QLocale::FloatingPointShortest).remove(",") + ",";
        }
        return _str;
    }

    QList<double> GlobalHelper::convertQStringToQListDouble(const QString& data)
    {
        QList<double> _list;
        auto _stringList = data.split(',');
        _stringList.removeAll("");
        bool _success = false;
        for (auto item : _stringList)
        {
            _list.append(item.toDouble(&_success));
        }
        return _list;
    }

    QString GlobalHelper::convertQVectorArrayQVectorDoubleToQString(const QVector<std::array<QVector<double>, 3>>& data)
    {
        QString _str;
        for (auto i = data.cbegin(); i != data.cend(); i++)
        {
            for (auto j = i->cbegin(); j != i->cend(); j++)
            {
                for (auto k = j->cbegin(); k != j->cend(); k++)
                {
                    _str = _str + QLocale().toString(*k, 'g', QLocale::FloatingPointShortest).remove(",") + ",";
                }
                _str += "|";
            }
            _str += "|";
        }
        return _str;
    }

    QVector<std::array<QVector<double>, 3>> GlobalHelper::convertQStringToQVectorArrayQVectorDouble(const QString& data)
    {
        QVector<std::array<QVector<double>, 3>> _vector;
        auto _stringList = data.split('|');
        _stringList.removeAll("");
        bool _success = false;
        QVector<double> _value;
        for (auto i = _stringList.cbegin(); i != _stringList.cend(); i++)
        {
            if (!i->isEmpty())
            {
                auto _j = i->split(',');
                _value.clear();
                for (auto a : _j)
                {
                    if (!a.isEmpty())
                    {
                        _value.append(a.toDouble(&_success));
                    }
                }
                if (_success)
                {
                    std::array<QVector<double>, 3> _temp;
                    _temp[0] = _value;
                    _temp[1] = _value;
                    _temp[2] = _value;
                    _vector.append(_temp);
                }
                else
                {
                    _vector.clear();
                    QString msg = QObject::tr("convert char* to QVector<std::array<QVector<double>, 3>> fail! content:%1").arg(data);
                    return _vector;
                }
            }   
        }
        return _vector;
    }

    QString GlobalHelper::convertQVectorQVectorDoubleToQString(const QVector<QVector<double>>& data)
    {
        QString _str;
        for (auto i = data.cbegin(); i != data.cend(); i++)
        {
            for (auto j = i->cbegin(); j != i->cend(); j++)
            {
                _str = _str + QLocale().toString(*j, 'g', QLocale::FloatingPointShortest).remove(",") + ",";
            }
            _str += "|";
        }
        return _str;
    }

    QVector<QVector<double>> GlobalHelper::convertQStringToQVectorQVectorDouble(const QString& data)
    {
        QVector<QVector<double>> _vector;
        auto _stringList = data.split('|');
        _stringList.removeAll("");
        bool _success = false;
        QVector<double> _value;
        for (auto i = _stringList.cbegin(); i != _stringList.cend(); i++)
        {
            if (!i->isEmpty())
            {
                auto _j = i->split(',');
                _value.clear();
                for (auto a : _j)
                {
                    if (!a.isEmpty())
                    {
                        _value.append(a.toDouble(&_success));
                    }
                }
                if (_success)
                {
                    _vector.append(_value);
                }
                else
                {
                    _vector.clear();
                    QString msg = QObject::tr("convert char* to QVector<QVector<double>> fail! content:%1").arg(data);
                    return _vector;
                }
            }
        }
        return _vector;
    }

    QString GlobalHelper::convertVectorPairQPointFIntToQString(const QVector<QPair<QPointF, int>>& vector)
    {
        QString result;

        // 遍历向量中的每个元素
        for (int i = 0; i < vector.size(); ++i)
        {
            const auto& pair = vector[i];
            const QPointF& point = pair.first;
            int value = pair.second;

            // 格式化每个元素为"x,y,value"格式
            result += QString("%1,%2,%3").arg(point.x()).arg(point.y()).arg(value);

            // 除了最后一个元素，都添加分隔符
            if (i != vector.size() - 1)
            {
                result += ";";
            }
        }

        return result;
    }

    QVector<QPair<QPointF, int>> GlobalHelper::convertQStringToVectorPairQPointFInt(const QString& str)
    {
        QVector<QPair<QPointF, int>> result;

        // 分割字符串获取每个元素
        QStringList elements = str.split(";");

        foreach (const QString& element, elements)
        {
            if (element.isEmpty())
                continue;

            // 分割元素获取x, y和value
            QStringList parts = element.split(",");
            if (parts.size() != 3)
                continue; // 格式错误则跳过

            bool xOk, yOk, valOk;
            qreal x = parts[0].toDouble(&xOk);
            qreal y = parts[1].toDouble(&yOk);
            int value = parts[2].toInt(&valOk);

            // 检查转换是否成功
            if (xOk && yOk && valOk)
            {
                result.append(qMakePair(QPointF(x, y), value));
            }
        }

        return result;
    }


    QString GlobalHelper::convertQHashIntQStringListToQString(const QHash<int, QStringList>& data)
    {
        QString _str;
        for (auto i = data.cbegin(); i != data.cend(); i++)
        {
            _str = _str + QString::number(i.key()) + "|";
            for (auto j = i.value().cbegin(); j != i.value().cend(); j++)
            {
                _str = _str + *j + ",";
            }
            _str = _str + "|";
        }
        return _str;
    }

    QHash<int, QStringList> GlobalHelper::convertQStringToQHashIntQStringList(const QString& data)
    {
        QHash<int, QStringList> result;

        if (data.isEmpty())
            return result;

        QStringList tokens = data.split('|', QString::KeepEmptyParts);

        if (!tokens.isEmpty() && tokens.last().isEmpty())
            tokens.removeLast();

        if (tokens.size() % 2 != 0)
            return result; // Format error, return empty hash

        for (int i = 0; i < tokens.size(); i += 2)
        {
            bool ok;
            int key = tokens[i].toInt(&ok);
            if (!ok)
                continue; // Skip invalid key

            QString valueStr = tokens[i + 1];
            QStringList values = valueStr.split(',', QString::KeepEmptyParts);

            if (!values.isEmpty() && values.last().isEmpty())
                values.removeLast();

            result.insert(key, values);
        }

        return result;
    }

    QString GlobalHelper::convertQMultiHashIntQStringToQString(const QMultiHash<int, QString>& data)
    {
        QString _str;
        for (auto i = data.cbegin(); i != data.cend(); i++)
        {
            _str = _str + QString::number(i.key()) + "," + i.value() + "|";
        }
        return _str;

    }

    QMultiHash<int, QString> GlobalHelper::convertQStringToQMultiHashIntQString(const QString& data)
    {
        QMultiHash<int, QString> result;
        auto _stringList = data.split('|');
        _stringList.removeAll("");
        bool _success = false;
        int _key;
        QString _value;
        for (QString item : _stringList)
        {
            auto _keyValueStr = item.split(',');
            _keyValueStr.removeAll("");
            if (_keyValueStr.count() == 2)
            {
                _key = _keyValueStr[0].toInt(&_success);
                _value = _keyValueStr[1];
                if (_success)
                {
                    result.insert(_key, _value);
                }
                else
                {
                    result.clear();
                    QString msg = QObject::tr("convert char* to QMultiHash<int, QString> fail! content:%1").arg(data);
                    return result;
                }
            }
        }
        return result;
    }

    void GlobalHelper::setFileTimes(const QString& filePath)
    {
        QFileInfo fileInfo(filePath);
        if (!fileInfo.exists())
        {
            qDebug() << "文件不存在: " << filePath;
            return;
        }

        QDateTime creationTime = fileInfo.birthTime();
        if (!creationTime.isValid())
        {
            qDebug() << "无法获取文件的创建时间: " << filePath;
            return;
        }

        QFile file(filePath);
        if (!file.open(QIODevice::ReadWrite))
        {
            qDebug() << "无法打开文件: " << filePath;
            return;
        }

        if (!file.setFileTime(creationTime, QFileDevice::FileModificationTime))
        {
            qDebug() << "无法设置文件的修改时间: " << filePath;
        }

        if (!file.setFileTime(creationTime, QFileDevice::FileAccessTime))
        {
            qDebug() << "无法设置文件的访问时间: " << filePath;
        }

        file.close();
    }

    void GlobalHelper::setSimulationDataFilePath(const QString& filePath)
    {
        m_simulationDataFilePath = filePath;
        if (getIsOpenProject())
            return;
        QString _SimulationDataTempPath = getSimulationDataTempDir();
        QList<QString> filePaths = m_simulationDataFilePath.split(',');
        for (const auto& filePath : filePaths)
        {
            QDir dir(filePath);
            if (!dir.exists())//有一个路径不存在就全部置空，防止错误
            {
                //m_simulationDataFilePath = "";
                //return;
            }
            else
            {             
                copyFolder(filePath, _SimulationDataTempPath + "/" + filePath.split('/').last(), true);
            }
        }
    }

    void GlobalHelper::createDomElement(QDomDocument* doc, QDomElement* rootElement, QString subElementName, QString subElementDomText)
    {
        QDomElement _element = doc->createElement(subElementName);
        QDomText _domText = doc->createTextNode(subElementDomText);
        _element.appendChild(_domText);
        rootElement->appendChild(_element);
    }

    QString GlobalHelper::getSimulationDataFilePath()
    {
        return m_simulationDataFilePath;
    }

    bool GlobalHelper::copyFolder(const QString& fromDir, const QString& toDir, bool coverFileIfExist)
    {
        QDir sourceDir(fromDir);
        QDir targetDir(toDir);

        if (!targetDir.exists())
        { // 如果目标目录不存在，则进行创建
            if (!targetDir.mkdir(targetDir.absolutePath()))
                return false;
        }

        QFileInfoList fileInfoList = sourceDir.entryInfoList();
        foreach (QFileInfo fileInfo, fileInfoList)
        {
            if (fileInfo.fileName() == "." || fileInfo.fileName() == "..")
                continue;

            if (fileInfo.isDir())
            { // 当为目录时，递归的进行copy
                if (!copyFolder(fileInfo.filePath(),
                                targetDir.filePath(fileInfo.fileName()),
                                coverFileIfExist))
                    return false;
            }
            else
            { // 当允许覆盖操作时，将旧文件进行删除操作
                if (coverFileIfExist && targetDir.exists(fileInfo.fileName()))
                {
                    targetDir.remove(fileInfo.fileName());
                }

                // 进行文件拷贝
                if (!QFile::copy(fileInfo.filePath(), targetDir.filePath(fileInfo.fileName())))
                {
                    return false;
                }
            }
        }
        return true;
    }

    bool GlobalHelper::createSimulationDataTempDir()
    {
        m_simulationDataTempFileDir = m_tempIODir + "/PostSimulationDatas";
        QDir dir;
        if (!dir.exists(m_simulationDataTempFileDir))
            dir.remove(m_simulationDataTempFileDir);
        dir.mkdir(m_simulationDataTempFileDir);
        return true;
    }
    QString GlobalHelper::getSimulationDataTempDir()
    {
        return m_simulationDataTempFileDir;
    }

    void GlobalHelper::createImportDataTempDir()
    {
        m_ImportDataTempFileDir = GlobalHelperInstance->getProjectTempIODir() + "/importDatas";
        QDir dir;
        if (!dir.exists(m_ImportDataTempFileDir))
            dir.mkdir(m_ImportDataTempFileDir);

    }

    QString GlobalHelper::getImportDataTempDir()
    {
        return m_ImportDataTempFileDir;
    }

    void GlobalHelper::setIsNeedPopupWindow(bool isNeedPopupWindow)
    {
        m_isNeedPopupWindow = isNeedPopupWindow;
    }
    bool GlobalHelper::getIsNeedPopupWindow()
    {
        return m_isNeedPopupWindow;
    }

    bool GlobalHelper::isDoubleValueInRange(double value, double min, double max)
    {
        return (value >= min) && (value <= max);
    }

    QString GlobalHelper::autoIncreaseName(QSet<QString>& names, QString name)
    {
        for (int i = 1; i < INT_MAX; ++i)
        {
            QString newName = name + "_" + QString::number(i);
            if (!names.contains(newName))
            {
                return newName;
            }
        }
    }

    QString GlobalHelper::hashToBase64(const QHash<int, QStringList>& hash)
    {
        QJsonObject root;
        for (auto it = hash.constBegin(); it != hash.constEnd(); ++it)
        {
            // 把 QStringList 转成 QJsonArray
            QJsonArray arr = QJsonArray::fromStringList(it.value());
            // 用 QString::number(int) 当 key
            root[QString::number(it.key())] = arr;
        }
        QJsonDocument doc(root);
        QString json = doc.toJson(QJsonDocument::Compact);
        return json.toUtf8().toBase64();
    }

    QHash<int, QStringList> GlobalHelper::base64ToHash(const QString& base64Str)
    {
        // Base64解码
        QString json = QString::fromUtf8(QByteArray::fromBase64(base64Str.toUtf8()));
        QHash<int, QStringList> result;
        QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
        if (!doc.isObject())
            return result;

        QJsonObject root = doc.object();
        for (auto it = root.begin(); it != root.end(); ++it)
        {
            bool ok = false;
            int key = it.key().toInt(&ok);
            if (!ok)
                continue; // key 不是数字就跳过
            QJsonArray arr = it.value().toArray();
            QStringList list;
            for (const QJsonValue& v : arr)
                list.append(v.toString());
            result.insert(key, list);
        }
        return result;
    }

    QString GlobalHelper::hashToJsonString(const QHash<QString, QString>& hash)
    {
        QJsonObject obj;
        for (auto it = hash.constBegin(); it != hash.constEnd(); ++it)
            obj.insert(it.key(), it.value());
        QString json =  QJsonDocument(obj).toJson(QJsonDocument::Compact);
        return json.toUtf8().toBase64();
    }

    QHash<QString, QString> GlobalHelper::jsonStringToHash(const QString& base64Str)
    {
        QString json = QString::fromUtf8(QByteArray::fromBase64(base64Str.toUtf8()));
        QHash<QString, QString> res;
        QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
        if (!doc.isObject())
            return res;
        QJsonObject obj = doc.object();
        for (auto it = obj.begin(); it != obj.end(); ++it)
            res.insert(it.key(), it.value().toString());
        return res;
    }

} // namespace BaseModule
